package controller

import (
	"encoding/json"
	"fmt"
	"io"
	"net/http"
	"strconv"

	"github.com/gin-gonic/gin"
	"go.uber.org/zap"

	"VideoManageSystem/internal/service"
)

// GetSimilarVideos 获取相似视频列表
func GetSimilarVideos(c *gin.Context) {
	// 从查询参数中获取 threshold，默认为 0.95
	thresholdStr := c.DefaultQuery("threshold", "0.95")
	threshold, err := strconv.ParseFloat(thresholdStr, 64)
	if err != nil {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "threshold 参数必须是有效的浮点数",
		})
		return
	}

	if threshold < 0 || threshold > 1 {
		c.JSON(400, gin.H{
			"code":    400,
			"message": "threshold 必须在 [0, 1] 范围内",
		})
		return
	}

	// 构造 VA 服务请求 URL
	url := fmt.Sprintf("http://127.0.0.1:6590/api/va/similar-videos?threshold=%f", threshold)

	// 发起 GET 请求到 VA 服务
	resp, err := http.Get(url)
	if err != nil {
		zap.L().Error("调用 VA 服务获取相似视频失败（网络错误）", zap.Error(err))
		c.JSON(500, gin.H{
			"code":    500,
			"message": "服务器内部错误：无法连接到视频分析服务",
		})
		return
	}
	defer resp.Body.Close()

	// 检查响应状态码
	if resp.StatusCode != http.StatusOK {
		body, _ := io.ReadAll(resp.Body)
		zap.L().Warn("VA 服务返回非200状态码",
			zap.Int("status", resp.StatusCode),
			zap.ByteString("response", body))
		c.JSON(500, gin.H{
			"code":    500,
			"message": fmt.Sprintf("视频分析服务异常，状态码：%d", resp.StatusCode),
		})
		return
	}

	// 解析响应数据
	var vaResp struct {
		Code    int    `json:"code"`
		Message string `json:"message"`
		Data    []struct {
			ReferenceVideo string             `json:"referenceVideo"`
			SimilarVideos  map[string]float64 `json:"similarVideos"`
		} `json:"data"`
	}

	if err := json.NewDecoder(resp.Body).Decode(&vaResp); err != nil {
		zap.L().Error("解析 VA 响应失败", zap.Error(err))
		c.JSON(500, gin.H{
			"code":    500,
			"message": "无法解析视频分析服务响应",
		})
		return
	}

	// 将结果转换为前端可用格式
	var result [][]map[string]interface{}

	for _, group := range vaResp.Data {
		var videoGroup []map[string]interface{}

		// 处理参考视频
		refVideo, err := service.GetVideoByIdFromSQL(group.ReferenceVideo)
		if err != nil {
			zap.L().Error("获取参考视频失败",
				zap.String("videoId", group.ReferenceVideo),
				zap.Error(err))
			continue // 跳过这组数据
		}

		refVideoMap := map[string]interface{}{
			"id":         refVideo.ID,
			"videoUrl":   refVideo.VideoURL,
			"coverUrl":   refVideo.CoverURL,
			"size":       refVideo.Size,
			"name":       refVideo.Name,
			"content":    refVideo.Content,
			"uploader":   refVideo.Uploader,
			"recordTime": refVideo.RecordTime,
			"uploadTime": refVideo.UploadTime,
			"filePath":   refVideo.FilePath,
			"similarity": 1.0, // 参考视频相似度为1
		}
		videoGroup = append(videoGroup, refVideoMap)

		// 处理相似视频
		for similarVideoId, similarity := range group.SimilarVideos {
			similarVideo, err := service.GetVideoByIdFromSQL(similarVideoId)
			if err != nil {
				zap.L().Error("获取相似视频失败",
					zap.String("videoId", similarVideoId),
					zap.Error(err))
				continue // 跳过这个视频
			}

			similarVideoMap := map[string]interface{}{
				"id":         similarVideo.ID,
				"videoUrl":   similarVideo.VideoURL,
				"coverUrl":   similarVideo.CoverURL,
				"size":       similarVideo.Size,
				"name":       similarVideo.Name,
				"content":    similarVideo.Content,
				"uploader":   similarVideo.Uploader,
				"recordTime": similarVideo.RecordTime,
				"uploadTime": similarVideo.UploadTime,
				"filePath":   similarVideo.FilePath,
				"similarity": similarity,
			}
			videoGroup = append(videoGroup, similarVideoMap)
		}

		result = append(result, videoGroup)
	}

	// 返回成功响应
	c.JSON(200, gin.H{
		"code":    200,
		"message": "获取相似视频成功",
		"data":    result,
	})
}
